package com.gylang.spring.netty;

import cn.hutool.core.collection.CollUtil;
import com.gylang.netty.sdk.IMServer;
import com.gylang.netty.sdk.api.config.DefaultGimConfigurationInitializerHelper;
import com.gylang.netty.sdk.api.config.GimGlobalConfiguration;
import com.gylang.netty.sdk.api.config.GimProperties;
import com.gylang.netty.sdk.api.conveter.DataConverter;
import com.gylang.netty.sdk.api.event.EventContext;
import com.gylang.netty.sdk.api.event.EventProvider;
import com.gylang.netty.sdk.api.event.message.MessageEventListener;
import com.gylang.netty.sdk.api.handler.BizRequestAdapter;
import com.gylang.netty.sdk.api.handler.IMessageRouter;
import com.gylang.netty.sdk.api.handler.qos.IMessageReceiveQosHandler;
import com.gylang.netty.sdk.api.handler.qos.IMessageSenderQosHandler;
import com.gylang.netty.sdk.api.initializer.CustomInitializer;
import com.gylang.netty.sdk.api.intercept.NettyIntercept;
import com.gylang.netty.sdk.api.provider.MessageProvider;
import com.gylang.netty.sdk.api.repo.GIMGroupSessionRepository;
import com.gylang.netty.sdk.api.repo.GIMSessionRepository;
import com.gylang.netty.sdk.api.repo.NettyUserInfoFillHandler;
import com.gylang.spring.netty.util.SpringUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author gylang
 * data 2020/12/1
 */
@Component
public class ServerStartEventListener implements ApplicationListener<ApplicationStartedEvent> {

	/**
	 * 根据名称装配，防止和客户端的ChannelInitializer冲突报错
	 */
	@Resource
	private List<CustomInitializer<?>> serverChannelInitializer;
	/** 事件监听 */
	@Resource
	private EventProvider eventProvider;
	/** 时间上下文 */
	/** 时间上下文 */
	@Resource
	private EventContext eventContext;
	/** 数据类型转化 */
	@Resource
	private DataConverter dataConverter;
	/** 单用户会话工厂 */
	@Resource
	private GIMSessionRepository sessionRepository;
	/** 用户组会话工厂 */
	@Resource
	private GIMGroupSessionRepository groupSessionRepository;
	/** 消息发送provider */
	@Resource
	private MessageProvider messageProvider;
	/** 事件监听列表 */
	@Autowired(required = false)
	private List<MessageEventListener<?>> messageEventListener;
	/** 业务请求适配器 */
	@Resource
	private List<BizRequestAdapter> bizRequestAdapterList;
	/** 适配分发器 */
	@Resource
	private IMessageRouter messageRouter;
	/** 线程池 */
	@Resource(name = "imExecutor")
	private ThreadPoolExecutor poolExecutor;
	/** 填充客户信息 */
	@Autowired(required = false)
	private NettyUserInfoFillHandler nettyUserInfoFillHandler;
	/** 消息处理拦截器 */
	@Autowired(required = false)
	private List<NettyIntercept> nettyInterceptList;
	@Resource
	private IMessageSenderQosHandler iMessageSenderQosHandler;
	@Resource
	private IMessageReceiveQosHandler iMessageReceiveQosHandler;
	@Resource
	private GimGlobalConfiguration gimGlobalConfiguration;
	@Resource
	private GimProperties gimProperties;


	@SneakyThrows
	@Override
	public void onApplicationEvent(ApplicationStartedEvent event) {

//        if (event.getApplicationContext().getParent() == null) {
		//root application context 没有parent，他就是老大.
		//需要执行的逻辑代码，当spring容器初始化完成后就会执行该方法。
//            System.out.println("\n\n\n\n\n______________\n\n\n加载了\n\n_________\n\n");
//        }
//        if (event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) {
		System.out.println("\n\n\n_________\n\n加载一次的 \n\n ________\n\n\n\n");

		if (!gimGlobalConfiguration.isOpen()) {
			if (null == SpringUtils.getApplicationContext()) {
				new SpringUtils().setApplicationContext(event.getApplicationContext());
			}
			gimGlobalConfiguration.setServerChannelInitializer(SpringUtils.getBeanNoCheck("customInitializerList"));
			if (CollUtil.isNotEmpty(gimGlobalConfiguration.getServerChannelInitializer())) {
				gimGlobalConfiguration.setEventProvider(SpringUtils.getBean(EventProvider.class));
				gimGlobalConfiguration.setEventContext(SpringUtils.getBeanNoCheck(EventContext.class));
				gimGlobalConfiguration.setDataConverter(SpringUtils.getBeanNoCheck(DataConverter.class));
				gimGlobalConfiguration.setSessionRepository(SpringUtils.getBeanNoCheck(GIMSessionRepository.class));
				gimGlobalConfiguration.setGroupSessionRepository(SpringUtils.getBeanNoCheck(GIMGroupSessionRepository.class));
				gimGlobalConfiguration.setMessageProvider(SpringUtils.getBeanNoCheck(MessageProvider.class));
				gimGlobalConfiguration.setMessageEventListener(SpringUtils.getBeanList(MessageEventListener.class));
				gimGlobalConfiguration.setBizRequestAdapterList(SpringUtils.getBeanList(BizRequestAdapter.class));
				gimGlobalConfiguration.setIMessageRouter(SpringUtils.getBeanNoCheck(IMessageRouter.class));
				gimGlobalConfiguration.setPoolExecutor(SpringUtils.getBeanNoCheck(ThreadPoolExecutor.class));
				gimGlobalConfiguration.setNettyUserInfoFillHandler(SpringUtils.getBeanNoCheck(NettyUserInfoFillHandler.class));
				gimGlobalConfiguration.setNettyInterceptList(SpringUtils.getBeanList(NettyIntercept.class));
				gimGlobalConfiguration.setIMessageReceiveQosHandler(SpringUtils.getBeanNoCheck(IMessageReceiveQosHandler.class));
				gimGlobalConfiguration.setIMessageSenderQosHandler(SpringUtils.getBeanNoCheck(IMessageSenderQosHandler.class));
				gimGlobalConfiguration.setGimProperties(SpringUtils.getBean(GimProperties.class));
				new DefaultGimConfigurationInitializerHelper().initConfig(gimGlobalConfiguration);
				gimGlobalConfiguration.setOpen(true);
				IMServer imServer = new IMServer();
				imServer.setNettyConfig(gimGlobalConfiguration);
				imServer.start();
			} else {

			}

		}


	}
}
